/**
 * Copyright 2011 Declan.z
 */
package com.mail163.email.location;

import java.util.Date;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;

import com.baidu.location.LocServiceMode;
import com.baidu.location.LocationClient;
import com.baidu.location.ReceiveListener;
import com.mail163.email.Logs;
import com.mail163.email.Email.Global;
import com.mail163.email.location.GearsLocationClient.OnGearsLocationListener;

/**
 * @author Declan.Z(declan.zhang@gmail.com)
 * @date 2011-12-16
 */
public class LocationService extends Service implements ReceiveListener,
		OnGearsLocationListener {

	private LocationBinder mBinder = new LocationBinder();

	private LocationClient mBaiduClient;
	private GearsLocationClient mGearClient;
	private Handler mHandler = new Handler();

	private Location mCurrentLocation; // 当前取到的位罄1�7

	private int mState = STATE_UNDO;

	public static final int STATE_UNDO = 1;
	public static final int STATE_DOING = 2;
	public static final int STATE_FIXING = 3;
	public static final int STATE_SUCCESS = 4;
	public static final int STATE_ERROR = 5;

	private boolean isBaiduFinish = false;
	private boolean isGearsFinish = false;

	private Date mGearsStartTime;
	private Date mBaiduStartTime;

	public static final String TYPE_BAIDU = "baidu";
	public static final String TYPE_GEARS = "google";

	@Override
	public IBinder onBind(Intent intent) {
		return mBinder;
	}

	@Override
	public void onCreate() {
		super.onCreate();
		mBaiduClient = new LocationClient(this);
		mBaiduClient.setTimeSpan(3000);
		mBaiduClient.setServiceMode(LocServiceMode.Immediat);
		mBaiduClient.setProdName("icd");
		mBaiduClient.setCoorType("gcj02");
		mBaiduClient.setAddrType("&addr=street|street_number");
		mGearClient = new GearsLocationClient(this);
		// if (((App) getApplicationContext()).getLastLocation() == null) {
		startLocation();
		// }
	}

	public void requestLocation() {
		requestLocation(false);
	}

	public void requestLocation(boolean isReLocation) {
		if (mState == STATE_ERROR // 定位失败的重新定佄1�7
		// || (isReLocation && mState == STATE_SUCCESS)
		) {
			startLocation(isReLocation);
		} else if (isReLocation) { // 重新定位
			if (mBaiduClient != null) {
				mBaiduClient.stop();
			}
			if (mGearClient != null) {
				mGearClient.stop();
			}
			startLocation(isReLocation);
		}
	}

	private void startLocation(boolean isRelocation) {
		mBaiduClient.start();
		startBaiduLocation(2500);

		mGearClient.start();
		startGoogleLocation();

		isBaiduFinish = false;
		isGearsFinish = false;

		mState = isRelocation ? STATE_FIXING : STATE_DOING;
		mCurrentLocation = isRelocation ? null : mCurrentLocation;
	}

	private void startLocation() {
		startLocation(false);
	}

	private void startBaiduLocation(int delay) {
		Logs.d(Logs.LOG_TAG, "startBaiduLocation");
		mBaiduClient.addRecerveListener(this);
		mHandler.postDelayed(new Runnable() {
			private int count = 0;

			@Override
			public void run() {
				while (mBaiduClient.getLocation() != 0 && count < 10) {
					try {
						Thread.sleep(500);
						count++;
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				mBaiduStartTime = new Date();
			}
		}, delay);
	}

	private void startGoogleLocation() {
		Logs.d(Logs.LOG_TAG, "startGoogleLocation");
		mGearClient.setOnGearsLocationListener(this);
		mGearClient.requestGearsLocation();
		mGearsStartTime = new Date();
	}

	@Override
	public void onReceive(String data) {
		Logs.d(Logs.LOG_TAG, "Baidu : " + data);
		if (data != null) {
			Location location = Location.parseBaidu(data);
			if (location != null) {
				location.locationTime = location.time.getTime()
						- mBaiduStartTime.getTime();
				upload(location, TYPE_BAIDU);
				sendLocationBroadcast(location);
			}
		}
		try {
			mBaiduClient.stop();
		} catch (Exception e) {
			e.printStackTrace();
		}
		// 只处理一次结构1�7
		isBaiduFinish = true;
		stateChange();
	}

	@Override
	public void onGearsLocationReturn(String data) {
		Logs.d(Logs.LOG_TAG, "Gear :" + data);
		if (data != null) {
			Location location = Location.parseGears(data);
			if (location != null) {
				location.locationTime = location.time.getTime()
						- mGearsStartTime.getTime();
				upload(location, TYPE_GEARS);
				sendLocationBroadcast(location);
			}
		}

		isGearsFinish = true;
		stateChange();
	}

	private void sendLocationBroadcast(Location location) {
		if (location != null) {
			if (mCurrentLocation == null
					|| mCurrentLocation.radius > location.radius
					|| mState == STATE_FIXING) {
				mCurrentLocation = location;

				// sendBroadcast(new
				// Intent(App.INTENT_ACTION_LOCATION).putExtra("location",
				// location));
			}

			StringBuffer str = new StringBuffer();
			str.append(location.addr);
			str.append(",");
			str.append(location.locationTime);
			str.append(",");
			str.append(location.radius);
			str.append(",");
			str.append(location.lng);
			Global.addressLoaction = location.addr;
			Logs.v(Logs.LOG_TAG, "loacation message :" + str.toString());
		}
	}

	private void stateChange() {
		if (isBaiduFinish && isGearsFinish) {
			if (mCurrentLocation == null) {
				mState = STATE_ERROR;
				// sendBroadcast(new Intent(App.INTENT_ACTION_LOCATION));
			} else {
				mState = STATE_SUCCESS;
			}
		}
	}

	private void upload(Location location, String type) {
		// HttpDataFetcher<Result> fetcher =
		// mApp.getApiManager().uploadLocation(this, location,
		// mGearClient == null ? null : mGearClient.getCellInfo()
		// , type);
		// fetcher.fetch();
	}

	@Override
	public void onDestroy() {
		super.onDestroy();
		try {
			if (mBaiduClient != null) {
				mBaiduClient.stop();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public class LocationBinder extends Binder {
		public LocationService getService() {
			return LocationService.this;
		}
	}

}
